import type {ModalApiOptions, ModalState} from './modal';

import {Store} from '@/utils/shared/store';
import {bindMethods, isFunction} from '@/utils/shared/utils';

export class ModalApi {
    private api: Pick<
        ModalApiOptions,
        | 'onBeforeClose'
        | 'onCancel'
        | 'onClosed'
        | 'onConfirm'
        | 'onOpenChange'
        | 'onOpened'
    >;
    // private prevState!: ModalState;
    private state!: ModalState;

    // 共享数据
    public sharedData: Record<'payload', any> = {
        payload: {},
    };

    public store: Store<ModalState>;

    constructor(options: ModalApiOptions = {}) {
        const {
            connectedComponent: _,
            onBeforeClose,
            onCancel,
            onClosed,
            onConfirm,
            onOpenChange,
            onOpened,
            ...storeState
        } = options;

        const defaultState: ModalState = {
            bordered: true,
            centered: false,
            class: '',
            closeOnClickModal: true,
            closeOnPressEscape: true,
            confirmDisabled: false,
            confirmLoading: false,
            contentClass: '',
            draggable: false,
            footer: true,
            footerClass: '',
            fullscreen: false,
            fullscreenButton: true,
            header: true,
            headerClass: '',
            isOpen: false,
            loading: false,
            modal: true,
            openAutoFocus: false,
            showCancelButton: true,
            showConfirmButton: true,
            title: '',
        };

        this.store = new Store<ModalState>(
            {
                ...defaultState,
                ...storeState,
            },
            {
                onUpdate: () => {
                    const state = this.store.state;

                    // 每次更新状态时，都会调用 onOpenChange 回调函数
                    if (state?.isOpen === this.state?.isOpen) {
                        this.state = state;
                    } else {
                        this.state = state;
                        this.api.onOpenChange?.(!!state?.isOpen);
                    }
                },
            },
        );

        this.state = this.store.state;

        this.api = {
            onBeforeClose,
            onCancel,
            onClosed,
            onConfirm,
            onOpenChange,
            onOpened,
        };
        bindMethods(this);
    }

    // 如果需要多次更新状态，可以使用 batch 方法
    batchStore(cb: () => void) {
        this.store.batch(cb);
    }

    /**
     * 关闭弹窗
     */
    close() {
        // 通过 onBeforeClose 钩子函数来判断是否允许关闭弹窗
        // 如果 onBeforeClose 返回 false，则不关闭弹窗
        const allowClose = this.api.onBeforeClose?.() ?? true;
        if (allowClose) {
            this.store.setState((prev) => ({...prev, isOpen: false}));
        }
    }

    getData<T extends object = Record<string, any>>() {
        return (this.sharedData?.payload ?? {}) as T;
    }

    /**
     * 取消操作
     */
    onCancel() {
        if (this.api.onCancel) {
            this.api.onCancel?.();
        } else {
            this.close();
        }
    }

    /**
     * 弹窗关闭动画播放完毕后的回调
     */
    onClosed() {
        if (!this.state.isOpen) {
            this.api.onClosed?.();
        }
    }

    /**
     * 确认操作
     */
    onConfirm() {
        this.api.onConfirm?.();
    }

    /**
     * 弹窗打开动画播放完毕后的回调
     */
    onOpened() {
        if (this.state.isOpen) {
            this.api.onOpened?.();
        }
    }

    open() {
        this.store.setState((prev) => ({...prev, isOpen: true}));
    }

    setData<T>(payload: T) {
        this.sharedData.payload = payload;
    }

    setState(
        stateOrFn:
            | ((prev: ModalState) => Partial<ModalState>)
            | Partial<ModalState>,
    ) {
        if (isFunction(stateOrFn)) {
            this.store.setState(stateOrFn);
        } else {
            this.store.setState((prev) => ({...prev, ...stateOrFn}));
        }
    }
}
